#pragma once

#include <QScrollArea>
#include <QWidget>
#include <QScrollbar>
#include <QEvent>
#include <QFile>
#include <QApplication>
#include <QTimer>
#include <QPushButton>

#include "log.hpp"

namespace utils {


class WidgetUtil : public QWidget
{
    Q_OBJECT
public:
    static QScrollArea* createQScrollArea()
    {
        QScrollArea* scrollArea = new QScrollArea();
        scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        scrollArea->setWidgetResizable(true);
        scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px }");

        applyScrollStyle(scrollArea);

        scrollArea->setStyleSheet("QScrollArea { border: none; }");

        return scrollArea;
    }

    static void applyScrollStyle(QAbstractScrollArea* area)
    {
        // 当鼠标进入滚动区域时，显示滚动条；离开时隐藏
        area->setMouseTracking(true); // 鼠标移动也触发 enter/leave 事件
        area->viewport()->setMouseTracking(true);

        // 创建并安装过滤器
        auto* filter = new ScrollEventFilter(area);
        area->installEventFilter(filter);
        area->viewport()->installEventFilter(filter);

        area->verticalScrollBar()->setStyleSheet(scrollbarHideStyle());
    }

    static inline QIcon makeIcon(const QByteArray& data)
    {
        QPixmap pixmap;
        pixmap.loadFromData(data);
        return QIcon(pixmap);
    }


private:
    static QString scrollbarShowStyle()
    {
        static QString scrollbarStyle = R"(
            QScrollBar:vertical {
                width: 6px;
                background: transparent;
                margin: 0px;
            }
            QScrollBar::handle:vertical {
                background-color: rgba(150, 150, 150, 150); /* 半透明灰色 */
                min-height: 20px;
                border-radius: 3px;
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                height: 0px;
            }
            QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
                background: none;
            }
        )";

        return scrollbarStyle;
    }

    static QString scrollbarHideStyle()
    {
        static QString scrollbarStyle = R"(
            QScrollBar:vertical {
                width: 6px;
                background: transparent;
                margin: 0px;
            }
            QScrollBar::handle:vertical {
                background-color: transparent; /* 隐藏滚动条 */
                min-height: 20px;
                border-radius: 3px;
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                height: 0px;
            }
            QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
                background: none;
            }
        )";

        return scrollbarStyle;
    }

    class ScrollEventFilter : public QObject
    {
    public:
        explicit ScrollEventFilter(QAbstractScrollArea* area) : QObject(area), area(area) {}

    protected:
        bool eventFilter(QObject* obj, QEvent* event) override
        {
            Q_UNUSED(obj);
            Q_UNUSED(event);

            if (event->type() == QEvent::Enter) {
                area->verticalScrollBar()->setStyleSheet(scrollbarShowStyle());
            } else if (event->type() == QEvent::Leave) {
                // 获取当前鼠标在窗口内的全局坐标
                QPoint globalPos = QCursor::pos();
                QPoint localPos = area->mapFromGlobal(globalPos);

                // 检查鼠标是否仍在滚动区域（包括滚动条）内
                if (!area->rect().contains(localPos)) {
                    area->verticalScrollBar()->setStyleSheet(scrollbarHideStyle());
                }
            }
            return false;
        }

    private:
        QAbstractScrollArea* area;
    };
};

class FileUtil
{
public:
    static inline QByteArray loadByteArrayFromFile(const QString& filename)
    {
        QFile file(filename);
        if(!file.open(QFile::ReadOnly)) {
            LOG(LL_ERROR, "file read error!");
            return QByteArray();
        }
        QByteArray data = file.readAll();
        file.close();
        return data;
    }

    static inline void writeByteArrayToFile(const QString& filename, const QByteArray& data)
    {
        QFile file(filename);
        if(!file.open(QFile::WriteOnly)) {
            LOG(LL_ERROR, "file write error!");
            return;
        }
        file.write(data);
        file.flush();       // 自己刷盘决策
        file.close();
    }

};


class TimeUtil : public QWidget
{
public:
    static inline QString formatTime(uint64_t timestamp)
    {
        QDateTime dateTime = QDateTime::fromSecsSinceEpoch(static_cast<time_t>(timestamp));
        return dateTime.toString("MM-dd HH:mm:ss");
    }

    static inline uint64_t getNowTime()
    {
        return QDateTime::currentSecsSinceEpoch();
    }

    static inline void buttonEnableCountDown(QTimer*& countdownTimer, QWidget* parent, QPushButton* btn, uint32_t countdown, uint32_t interval, bool immediateStart)
    {
        if(!countdownTimer) {
            countdownTimer = new QTimer(parent);
        }
        countdown_ = countdown;
        disconnect(countdownTimer, &QTimer::timeout, parent, nullptr);
        connect(countdownTimer, &QTimer::timeout, parent, [=](){
            if (countdown_ <= 0) {
                btn->setEnabled(true);
                btn->setText("获取验证码");
                countdownTimer->stop();
                return;
            }
            --countdown_;
            btn->setText(QString::number(countdown_) + "s");
        });
        countdownTimer->start(interval);
        if(immediateStart) {
            QMetaObject::invokeMethod(countdownTimer, "timeout");
        }
    }

    static inline void buttonCountDownStop(QPushButton* btn)
    {
        btn->setEnabled(true);
        btn->setText("获取验证码");
        countdown_ = 0;
    }

public:
    static inline uint32_t countdown_ = 0;
};

class StringUtil
{
public:
    static QString stringTruncated(const QString& str, int maxWidth, const QFont& font = QApplication::font())
    {
        QFontMetrics metrics(font);
        int strWidth = metrics.horizontalAdvance(str);
        if(strWidth >= maxWidth) {
            QString ellipsis = "…";
            int ellipsisWidth = metrics.horizontalAdvance(ellipsis);
            int realStrWidth = maxWidth - ellipsisWidth;
            // 取左侧 n 个字符
            QString truncatedName = str.left(str.length() * realStrWidth / strWidth);
            return truncatedName + ellipsis;
        }
        return str;
    }
};

}

